package com.aaa.system.aop;

import com.aaa.system.aop.annotation.Log;
import com.aaa.system.dao.DictDataDao;
import com.aaa.system.service.IOperLogService;
import com.alibaba.fastjson.JSON;
import com.aaa.entity.OperLog;
import com.aaa.utils.JWTUtils;
import com.aaa.utils.WebUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * @author Lei
 * @create 2023-03-23 22:39
 */

@Component
@Aspect
public class OperLogAspect {

    @Autowired
    private IOperLogService operLogService;


    //定义切点:使用该注解（Log）的地方就是一个切入点
    @Pointcut(value = "@annotation(com.aaa.system.aop.annotation.Log)")
    private void pointcut(){};

    /** 定义通知
     * @AfterReturning:在执行完后获取返回值时通知
     * @AfterThrowing：在执行完后抛出异常时通知
     */
    @AfterReturning(value = "pointcut()",returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result){

        //Signature接口转化为实现类，需要强制类型转换
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取使用了Log注解方法的方法对象
        Method method = signature.getMethod();
        //拿到方法上的Log注解
        Log annotation = method.getAnnotation(Log.class);

        //1、日志标题
        String title = annotation.title();
        //2、业务类型
        String business_type = annotation.business_type();
        //3、方法名
        String methodName = method.getName();
        //4、请求类型
        HttpServletRequest request = WebUtil.getRequest();
        String requestMethod = request.getMethod();
        //5、操作类别
        Integer operator_type = annotation.operator_type();
        //6、操作人员
        String token = request.getHeader("token");
        Map<String, Object> tokenInfo = JWTUtils.getInfo(token);
        String oper_name = tokenInfo.get("username").toString();

        //7、操作路径
        String servletPath = request.getServletPath();
        //8、操作IP
        String oper_url = request.getRemoteAddr();
        //9、操作地址
        String oper_location = oper_url.startsWith("192.168.")?"内网IP":"外网IP";
        //10、操作参数
        Object[] args = joinPoint.getArgs();

        String oper_param = JSON.toJSONString(args);
        //11、返回结果
        String json_result = JSON.toJSONString(result);
        //12、操作状态
        String status = "0";
        //13、异常信息

        //14、操作时间
        LocalDateTime oper_date = LocalDateTime.now();

        OperLog operLog = new OperLog(null,title,business_type,methodName,requestMethod,operator_type,oper_name,servletPath,oper_url,oper_location,oper_param,json_result,status,null,oper_date);

        operLogService.insertOperLog(operLog);
    }

    @AfterThrowing(value = "pointcut()",throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, Throwable e){
        //Signature接口转化为实现类，需要强制类型转换
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取使用了Log注解方法的方法对象
        Method method = signature.getMethod();
        //拿到方法上的Log注解
        Log annotation = method.getAnnotation(Log.class);

        //1、日志标题
        String title = annotation.title();
        //2、业务类型
        String business_type = annotation.business_type();
        //3、方法名
        String methodName = method.getName();
        //4、请求类型
        HttpServletRequest request = WebUtil.getRequest();
        String requestMethod = request.getMethod();
        //5、操作类别
        Integer operator_type = annotation.operator_type();
        //6、操作人员
        String token = request.getHeader("token");
        Map<String, Object> tokenInfo = JWTUtils.getInfo(token);
        String oper_name = tokenInfo.get("username").toString();
        //7、操作路径
        String servletPath = request.getServletPath();
        //8、操作IP
        String oper_url = request.getRemoteAddr();
        //9、操作地址
        String oper_location = oper_url.startsWith("192.168.")?"内网IP":"外网IP";
        //10、操作参数
        Object[] args = joinPoint.getArgs();
        String oper_param = JSON.toJSONString(args);
        //11、返回结果

        //12、操作状态
        String status = "1";
        //13、异常信息  substring
        String error_msg = e.getMessage();
        // String subString = e.getMessage();
        // String error_msg = "";
        // if (subString.length()>1000){
        //     error_msg = subString.substring(0, 1000);
        // }else {
        //     error_msg = subString;
        // }

        //14、操作时间
        LocalDateTime oper_date = LocalDateTime.now();

        OperLog operLog = new OperLog(null,title,business_type,methodName,requestMethod,operator_type,oper_name,servletPath,oper_url,oper_location,oper_param,null,status,error_msg,oper_date);

        operLogService.insertOperLog(operLog);
    }

}
